using Cysharp.Threading.Tasks;
using IQIGame.Onigao.Framework;
using IQIGame.Onigao.Game;

namespace IQIGame.Onigao.GamePlay
{
    public enum NetTipStatus
    {
        GameSessionClosed,
        GameSessionDisconnected,
        GameSessionReconnectSuccess,
        LogicSessionClosed,
        LogicSessionDisconnected,
        LogicSessionReconnectSuccess,
    }

    public class NetTipController : Singleton<NetTipController>
    {
        private NetTipController()
        {
        }

        /// <summary>
        /// 记录logicSession的状态, 因为logicSession的状态处理可能会被gameSession顶掉, 需要在gameSession的状态处理完毕后再重新处理logicSession的状态
        /// </summary>
        private bool logicSessionIsDisconnected = false;
        /// <summary>
        /// 记录logicSession的状态, 因为logicSession的状态处理可能会被gameSession顶掉, 需要在gameSession的状态处理完毕后再重新处理logicSession的状态
        /// </summary>
        private bool logicSessionIsClosed = false;

        public void UpdateStatus(NetTipStatus updateReason)
        {
            NetSession gameSession = NetManager.Instance.GetSession(NetworkChannelName.Game);
            NetSession logicSession = NetManager.Instance.GetSession(NetworkChannelName.Logic);

            switch (updateReason)
            {
                case NetTipStatus.GameSessionClosed:
                    {
                        UD_NetTip uiData = UD_NetTip.NewFromPool();
                        uiData.content = TableCenter.text.Get(1000002).Text;// "游戏服网络连接断开"
                        uiData.cancelAction = ConfirmGameSessionClosed;
                        ManagerCenter.UI.ShowWindowSync<UINetTip>(uiData);
                    }
                    break;
                case NetTipStatus.GameSessionDisconnected:
                    {
                        UD_NetTip uiData = UD_NetTip.NewFromPool();
                        uiData.content = TableCenter.text.Get(1000002).Text;// "游戏服网络连接断开"
                        uiData.cancelAction = ConfirmGameSessionClosed;
                        uiData.connectAction = UserClickGameReconnect;
                        ManagerCenter.UI.ShowWindowSync<UINetTip>(uiData);
                    }
                    break;
                case NetTipStatus.GameSessionReconnectSuccess:
                    {
                        bool _logicSessionIsDisconnected = logicSessionIsDisconnected;
                        bool _logicSessionIsClosed = logicSessionIsClosed;
                        logicSessionIsDisconnected = false;
                        logicSessionIsClosed = false;
                        if (logicSession == null)
                        {
                            //说明逻辑服session的状态已经处理完毕, 不用再处理
                        }
                        else if (logicSession.IsClosed)
                        {
                            if (_logicSessionIsClosed)
                            {
                                ConfirmLogicSessionClosed();
                            }
                        }
                        else if (!logicSession.IsAvailable)
                        {
                            if (_logicSessionIsDisconnected)
                            {
                                UserClickLogicReconnect();
                            }
                        }
                    }
                    break;
                case NetTipStatus.LogicSessionClosed:
                    {
                        if (gameSession == null)
                        {
                            break;
                        }
                        logicSessionIsClosed = true;
                        if (gameSession.IsAvailable)
                        {
                            UD_NetTip uiData = UD_NetTip.NewFromPool();
                            uiData.content = TableCenter.text.Get(1000003).Text; //"逻辑服网络连接断开";
                            uiData.cancelAction = ConfirmLogicSessionClosed;
                            ManagerCenter.UI.ShowWindowSync<UINetTip>(uiData);
                        }
                    }
                    break;
                case NetTipStatus.LogicSessionDisconnected:
                    {
                        if (gameSession == null)
                        {
                            break;
                        }
                        logicSessionIsDisconnected = true;
                        if (gameSession.IsAvailable)
                        {
                            UD_NetTip uiData = UD_NetTip.NewFromPool();
                            uiData.content = TableCenter.text.Get(1000003).Text; //"逻辑服网络连接断开";
                            uiData.cancelAction = ConfirmLogicSessionClosed;
                            uiData.connectAction = UserClickLogicReconnect;
                            ManagerCenter.UI.ShowWindowSync<UINetTip>(uiData);
                        }
                    }
                    break;
                case NetTipStatus.LogicSessionReconnectSuccess:
                    {
                        logicSessionIsDisconnected = false;
                        logicSessionIsClosed = false;
                    }
                    break;
                default:
                    break;
            }
        }

        /// <summary>
        /// 用户确认断开游戏服连接
        /// </summary>
        private void ConfirmGameSessionClosed()
        {
            NetManager.Instance.DestroySession(NetworkChannelName.Game);//这里可以不DestroySession, 只是为了保持统一, ProcedureReset会DestroyAllSession
            ProcedureFSM.Instance.ChangeState<ProcedureReset>();
        }

        /// <summary>
        /// 处理手动重连游戏服
        /// </summary>
        private async void UserClickGameReconnect()
        {
            NetSession gameSession = NetManager.Instance.GetSession(NetworkChannelName.Game);
            if (gameSession == null)
            {
                //理论上不会走到这里
                LogGame.LogError("error net status UserClickGameReconnect");
                ProcedureFSM.Instance.ChangeState<ProcedureReset>();
                return;
            }
            if (gameSession.IsAvailable)
            {
                return;
            }
            if (gameSession.CanReconnect())
            {
                bool netResult = await gameSession.Reconnect();
                if (!netResult)
                {
                    // 网络不通, 继续让玩家手动重连
                    await UniTask.Delay(1000); //延迟1秒, 让界面慢一点弹出, 优化玩家体验
                    UpdateStatus(NetTipStatus.GameSessionDisconnected);
                }
                else
                {
                    //网络通了, 协议重连成功不用做任何处理, 协议重连失败会走到SessionClosed
                }
            }
            else
            {
                if (!gameSession.IsClosed)
                {
                    gameSession.Close();
                }
                else
                {
                    UpdateStatus(NetTipStatus.GameSessionClosed);
                }
            }
        }

        /// <summary>
        /// 用户确认断开逻辑服连接
        /// </summary>
        private void ConfirmLogicSessionClosed()
        {
            logicSessionIsClosed = false;
            logicSessionIsDisconnected = false;
            NetManager.Instance.DestroySession(NetworkChannelName.Logic);//这里必须DestroySession
            GameplayAreaManager.Instance.SwitchAwait(GameplayAreaType.MainCity).Forget();
        }

        /// <summary>
        /// 处理手动重连逻辑服
        /// </summary>
        private async void UserClickLogicReconnect()
        {
            logicSessionIsClosed = false;
            logicSessionIsDisconnected = false;
            NetSession logicSession = NetManager.Instance.GetSession(NetworkChannelName.Logic);
            if (logicSession == null)
            {
                //理论上不会走到这里
                LogGame.LogError("error net status UserClickLogicReconnect");
                return;
            }
            if (logicSession.IsAvailable)
            {
                return;
            }
            if (logicSession.CanReconnect())
            {
                bool netResult = await logicSession.Reconnect();
                if (!netResult)
                {
                    // 网络不通, 继续让玩家手动重连
                    await UniTask.Delay(1000); //延迟1秒, 让界面慢一点弹出, 优化玩家体验
                    UpdateStatus(NetTipStatus.LogicSessionDisconnected);
                }
                else
                {
                    //网络通了, 协议重连成功不用做任何处理, 协议重连失败会走到SessionClosed
                }
            }
            else
            {
                if (!logicSession.IsClosed)
                {
                    logicSession.Close();
                }
                else
                {
                    UpdateStatus(NetTipStatus.LogicSessionClosed);
                }
            }
        }

        public void Clear()
        {
            logicSessionIsDisconnected = false;
            logicSessionIsClosed = false;
            ManagerCenter.UI.CloseWindow<UINetTip>();
        }
    }
}
